﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MWRCommunicationLibrary
{
    public abstract class DecodeOperation
    {

        public static object DecodeData(byte[] buffer, ParamDecodorAttribute attr)
        {
            int start = attr.StartIndex;
            int bIndexOff = start % 8;//目标起点偏移量，需右移
            int bIndex = start / 8;//目标起点对应字节序号

            int bLen = (attr.Length + bIndexOff) / 8;//目标占字节数
            bLen = (attr.Length + bIndexOff) % 8 > 0 ? bLen + 1 : bLen;
            int bLenStartOff = bLen > 1 ? (8 - bIndexOff) : attr.Length;//目标起点所在字节的有效位数
            bLenStartOff = bLenStartOff == 0 ? 8 : bLenStartOff;
            int bLenEndOff = (attr.Length + bIndexOff) % 8;//目标终点所在字节的有效位数
            bLenEndOff = bLenEndOff == 0 ? 8 : bLenEndOff;

            if (bLen == 0)
            {
                int count = attr.Length % 8;
                int result = (buffer[bIndex] >> bIndexOff ) & ((int)Math.Pow(2, count) - 1);

                return result * attr.Res + attr.Offset;
            }
            else
            {
                int result = 0;
                int leftCount = 0;
                for(int i = 0;i < bLen;i++)
                {
                    if(i == 0)
                    {
                        result += (buffer[bIndex] >> bIndexOff) & ((int)Math.Pow(2, bLenStartOff) - 1);
                        leftCount += 8 - bIndexOff;
                        continue;
                    }
                    else if(i == bLen - 1)
                    {
                        result += (buffer[bIndex - i] & ((int)Math.Pow(2, bLenEndOff) - 1)) << leftCount;
                    }
                    else
                    {
                        result += buffer[bIndex - i] << leftCount;
                        leftCount += 8;
                    }
                }

                return result * attr.Res + attr.Offset;
            }
        }

        public static int ConvertValueSender(bool value)
        {
            if(value)
            {
                return 1;
            }
            else
            {
                return 0;
            }
        }

        public static int ConvertValueSender(int value, ParamDecodorAttribute attr)
        {
            double res = attr.Res;
            double off = attr.Offset;

            var result = (value - off) / res;
            return (int)result;
        }

        public static int ConvertValueSender(double value, ParamDecodorAttribute attr)
        {
            double res = attr.Res;
            double off = attr.Offset;

            var result = (value - off) / res;
            return (int)result;
        }

        public static void AssembleMsg(ParamDecodorAttribute attr, int value, ref byte[] msg)
        {
            int start = attr.StartIndex;
            int bIndexOff = start % 8;//目标起点偏移量，需右移
            int bIndex = start / 8;//目标起点对应字节序号

            int bLen = (attr.Length + bIndexOff) / 8;//目标占字节数
            bLen = (attr.Length + bIndexOff) % 8 > 0 ? bLen + 1 : bLen;
            int bLenStartOff = bLen > 1 ? (8 - bIndexOff) : attr.Length;//目标起点所在字节的有效位数
            bLenStartOff = bLenStartOff == 0 ? 8 : bLenStartOff;
            int bLenEndOff = (attr.Length + bIndexOff) % 8;//目标终点所在字节的有效位数
            bLenEndOff = bLenEndOff == 0 ? 8 : bLenEndOff;

            if(bLen == 0)
            {
                int bValue = value << bIndexOff;
                int temp = 0xff - ((int)Math.Pow(2, bLenEndOff) - 1);
                msg[bIndex] = (byte)(msg[bIndex] | (bValue & temp));
            }
            else
            {
                byte[] bValue = BitConverter.GetBytes(value);

                for (int i = 0; i < bLen; i++)
                {
                    if (i == 0)
                    {
                        byte bbValue = (byte)(bValue[i] << bIndexOff);
                        int temp = 0xff - ((int)Math.Pow(2, bIndexOff) - 1);
                        msg[bIndex] = (byte)(msg[bIndex] | (bbValue & temp));
                    }
                    else
                    {
                        byte bbValue;
                        if(bIndexOff == 0)
                        {
                            bbValue = bValue[i];
                        }
                        else
                        {
                            bbValue = (byte)((bValue[i - 1] >> (8 - bIndexOff)) | (bValue[i] << bIndexOff));
                        }
                        msg[bIndex - i] = (byte)(msg[bIndex - i] | (bbValue));
                    }
                }
            }
        }
    }
}
